#ifndef __ODEFINE_H__
#define __ODEFINE_H__

// #define _CRTDBG_MAP_ALLOC
// #include <stdlib.h>
// #include <crtdbg.h>

#include <string>
using std::string;
#include <vector>
using std::vector;
#include <stack>
using std::stack;
#include <sstream>
using std::ostringstream;
#include <functional>
using std::function;
#include <unordered_map>
using std::unordered_map;
#include "cocos2d.h"
using namespace cocos2d;
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
#include "cocos2dx_support/CCLuaEngine.h"
#include "boost/foreach.hpp"
#include "boost/ptr_container/ptr_vector.hpp"
using boost::ptr_vector;
#include "hash_strmap.hpp"
#include "fd/delegate.hpp"
using fd::delegate;
#include "Box2D/Box2D.h"

inline float oR2D(float r)
{
	return ( 180.0f / b2_pi ) * r;
}

inline float oD2R(float d)
{
	return ( b2_pi / 180.0f ) * d ;
}

#define PROPERTY(varType, varName, funName)\
protected: varType varName;\
public: varType get##funName() const;\
public: void set##funName(varType var)

#define PROPERTY_BOOL(varName, funName)\
protected: bool varName;\
public: bool is##funName() const;\
public: void set##funName(bool var)

#define PROPERTY_NAME(varType, funName)\
public: varType get##funName() const;\
public: void set##funName(varType var)

#define PROPERTY_REF(varType, varName, funName)\
protected: varType varName;\
public: const varType& get##funName(void) const;\
public: void set##funName(const varType& var)

#define PROPERTY_NAME_REF(varType, funName)\
public: const varType& get##funName(void) const;\
public: void set##funName(const varType& var)

#define PROPERTY_VIRTUAL(varType, varName, funName)\
protected: varType varName;\
public: varType get##funName() const;\
public: virtual void set##funName(varType var)

#define PROPERTY_READONLY(varType, funName)\
public: varType get##funName() const

#define PROPERTY_READONLY_REF(varType, funName)\
public: const varType& get##funName(void) const

#define BLOCK_START do
#define BREAK_IF(cond) if(cond)break
#define BREAK_NOT(cond) if(!cond)break
#define BLOCK_END while(false);

#define SAFE_RELEASE(x) if(x)x->release()
#define SAFE_RELEASE_NULL(x) if(x){x->release();x=nullptr;}

void oGetPosFromStr(const char* str, float& x, float& y);

/** Use switch_string as below.

	string str = "abc";
	switch_string(str)
	{
		case_string("Pig")
		{
			break;
		}
		case_string("Dog")
		{
			break;
		}
	}
	end_switch;

@Caution Hash codes may have collisions!
 Check the hash codes before use.
*/
size_t oFNVHash(const char* str);
size_t oFNVHash(const string& str);
#define switch_string(x) size_t __strHashCode = oFNVHash(x);do
#define __case_string0(x, name, line) static size_t name##line = oFNVHash(x);if (__strHashCode == name##line)
#define __case_string1(x, line) __case_string0(x, __strCase, line)
#define case_string(x) __case_string1(x, __LINE__)
#define end_switch while (false)

#ifdef _OEXPORT_DLL_
	#define oDLL __declspec(dllexport)
#elif _OIMPORT_DLL_
	#define oDLL __declspec(dllimport)
#else
	#define oDLL
#endif

#endif
